package com.hongpu.controller;


import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hongpu.domain.HpProjectWorkPay;
import com.hongpu.domain.HpProjectWorkPayList;
import com.hongpu.dto.TotalReceiptsDto;
import com.hongpu.dto.UnpaidAmountDto;
import com.hongpu.enums.IncomeAndExpenditureTypesEnum;
import com.hongpu.enums.InvoiceTypeEnum;
import com.hongpu.service.HpProjectWorkPayListService;
import com.hongpu.service.HpProjectWorkPayService;
import com.hongpu.utils.ResultDto;
import com.hongpu.vo.*;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author 张玉胜
 * @since 2025年04月25日
 */
@Slf4j
@RestController
@RequestMapping("/hpProjectWorkPayList")
public class HpProjectWorkPayListController {
    @Autowired
    HpProjectWorkPayListService hpProjectWorkPayListService;
    @Autowired
    HpProjectWorkPayService hpProjectWorkPayService;

    /**
     * 新增
     */
    @PostMapping("/add")
    public ResultDto add(@RequestBody HpProjectWorkPay hpProjectWorkPay) {
        boolean save = hpProjectWorkPayListService.add(hpProjectWorkPay);
        if (save) {
            return ResultDto.ok();
        }
        return ResultDto.fail();
    }

    /**
     * 查询收款详情分页
     */
    @PostMapping("/pageOnClickProjectName")
    public ResultDto page(@RequestBody HpProjectWorkPay hpProjectWorkPay) {
        Map<String, Object> result = new HashMap<>();
        QueryWrapper<HpProjectWorkPay> queryWrapper = new QueryWrapper<>();
        String projectName = hpProjectWorkPay.getProjectName();
        if(StringUtils.isNotEmpty(projectName)){
            queryWrapper.eq("project_name", projectName);
        }
        queryWrapper.eq("income_and_expenditure_types", IncomeAndExpenditureTypesEnum.INCOME.getValue());
        HpProjectWorkPay projectWorkPay = hpProjectWorkPayService.getOne(queryWrapper);
        if(projectWorkPay == null){
            projectWorkPay = new HpProjectWorkPay();
            projectWorkPay.setProjectName(projectName);
        }else {
            // 统计  已收款总额  和 未收款总额
            TotalReceiptsDto totalReceiptsDto = hpProjectWorkPayListService.totalReceipts(IncomeAndExpenditureTypesEnum.INCOME.getValue(),projectName);
            BigDecimal totalAmountPaid = totalReceiptsDto.getOperated();
            BigDecimal totalAmountUnpaid = totalReceiptsDto.getNotOperated();
            projectWorkPay.setTotalAmountPaid(totalAmountPaid);
            projectWorkPay.setTotalAmountUnpaid(totalAmountUnpaid);

            // 增值税总额
            BigDecimal totalValueAddedTax =  BigDecimal.ZERO;
            // 普通税总额
            BigDecimal totalAmountOfOrdinaryTax =  BigDecimal.ZERO;
            // 这个ID用于统计 增值税总额和普通税总额
            Long projectWorkPayId = projectWorkPay.getId();
            List<InvoiceTaxAmountStatisticsVo> amountStatisticsVoList = hpProjectWorkPayListService.collectionTaxStatistics(projectWorkPayId, IncomeAndExpenditureTypesEnum.INCOME.getValue());
            if(CollectionUtils.isNotEmpty(amountStatisticsVoList)){
                for (InvoiceTaxAmountStatisticsVo amountStatisticsVo : amountStatisticsVoList) {
                    Integer invoiceType = amountStatisticsVo.getInvoiceType();
                    if(InvoiceTypeEnum.ORDINARY_INVOICES.getValue().equals(invoiceType)){
                        totalAmountOfOrdinaryTax = amountStatisticsVo.getAmount();
                    }else if(InvoiceTypeEnum.VALUE_ADDED_TAX_INVOICE.getValue().equals(invoiceType)){
                        totalValueAddedTax = amountStatisticsVo.getAmount();
                    }
                }
            }
            projectWorkPay.setTotalAmountOfOrdinaryTax(totalAmountOfOrdinaryTax);
            projectWorkPay.setTotalValueAddedTax(totalValueAddedTax);
        }
        // 查询 HpProjectWorkPay 对象
        result.put("hpProjectWorkPay", projectWorkPay);
        if(projectWorkPay != null){
            Page<?> page = new Page<>();
            page.setCurrent(hpProjectWorkPay.getCurrent());
            page.setSize(hpProjectWorkPay.getSize());
            IPage<HpProjectWorkPayListVo> selectPage = hpProjectWorkPayListService.selectPageInCome(page, projectWorkPay.getProjectName());
            result.put("selectPage", selectPage);
            return ResultDto.ok(result);
        }else {
            return ResultDto.ok();
        }

    }

    /**
     * 点击支出查询详情分页
     */
    @PostMapping("/pageOnClickExpenses")
    public ResultDto pageOnClickExpenses(Page<?> page, @RequestBody HpProjectWorkPay hpProjectWorkPay) {
        Map<String, Object> result = new HashMap<>();
        QueryWrapper<HpProjectWorkPay> queryWrapper = new QueryWrapper<>();
        String projectName = hpProjectWorkPay.getProjectName();
        if(StringUtils.isNotEmpty(projectName)){
            queryWrapper.eq("project_name", projectName);
        }
        queryWrapper.eq("income_and_expenditure_types", IncomeAndExpenditureTypesEnum.EXPENDITURE.getValue());
        HpProjectWorkPay projectWorkPay = hpProjectWorkPayService.getOne(queryWrapper);
        if(projectWorkPay == null){
            projectWorkPay = new HpProjectWorkPay();
            projectWorkPay.setProjectName(projectName);
        }
        // 查询 HpProjectWorkPay 对象
        result.put("hpProjectWorkPay", projectWorkPay);
        if(projectWorkPay != null){
            IPage<HpProjectWorkPayListVo> selectPage = hpProjectWorkPayListService.selectPageExpenses(page, projectWorkPay.getProjectName());
            result.put("selectPage", selectPage);
            return ResultDto.ok(result);
        }else {
            return ResultDto.ok();
        }

    }

    /**
     * 点击支出查询详情分页
     */
    @PostMapping("/pageOnClickExpenses2")
    public ResultDto pageOnClickExpenses2(@RequestBody HpProjectWorkPay hpProjectWorkPay) {
        Map<String, Object> result = new HashMap<>();
        QueryWrapper<HpProjectWorkPay> queryWrapper = new QueryWrapper<>();
        String projectName = hpProjectWorkPay.getProjectName();
        if(StringUtils.isNotEmpty(projectName)){
            queryWrapper.eq("project_name", projectName);
        }
        queryWrapper.eq("income_and_expenditure_types", IncomeAndExpenditureTypesEnum.EXPENDITURE.getValue());
        HpProjectWorkPay projectWorkPay = hpProjectWorkPayService.getOne(queryWrapper);
        if(projectWorkPay == null){
            projectWorkPay = new HpProjectWorkPay();
            projectWorkPay.setProjectName(projectName);
        }else {

            // 统计  已支出总额  和 未支出总额
            TotalReceiptsDto totalReceiptsDto = hpProjectWorkPayListService.totalReceipts(IncomeAndExpenditureTypesEnum.EXPENDITURE.getValue(),projectName);
            BigDecimal totalAmountPaid = totalReceiptsDto.getOperated();
            BigDecimal totalAmountUnpaid = totalReceiptsDto.getNotOperated();
            // 支付合同的合同总金额
            BigDecimal totalContractAmount = totalReceiptsDto.getTotalContractAmount();
            projectWorkPay.setTotalAmountPaid(totalAmountPaid);
            projectWorkPay.setTotalAmountUnpaid(totalAmountUnpaid);
            projectWorkPay.setTotalContractAmount(totalContractAmount);
            // 增值税总额
            BigDecimal totalValueAddedTax =  BigDecimal.ZERO;
            // 普通税总额
            BigDecimal totalAmountOfOrdinaryTax =  BigDecimal.ZERO;
            // 这个ID用于统计 增值税总额和普通税总额
            Long projectWorkPayId = projectWorkPay.getId();
            List<InvoiceTaxAmountStatisticsVo> amountStatisticsVoList = hpProjectWorkPayListService.collectionTaxStatistics(projectWorkPayId, IncomeAndExpenditureTypesEnum.EXPENDITURE.getValue());
            if(CollectionUtils.isNotEmpty(amountStatisticsVoList)){
                for (InvoiceTaxAmountStatisticsVo amountStatisticsVo : amountStatisticsVoList) {
                    Integer invoiceType = amountStatisticsVo.getInvoiceType();
                    if(InvoiceTypeEnum.ORDINARY_INVOICES.getValue().equals(invoiceType)){
                        totalAmountOfOrdinaryTax = amountStatisticsVo.getAmount();
                    }else if(InvoiceTypeEnum.VALUE_ADDED_TAX_INVOICE.getValue().equals(invoiceType)){
                        totalValueAddedTax = amountStatisticsVo.getAmount();
                    }
                }
            }
            projectWorkPay.setTotalAmountOfOrdinaryTax(totalAmountOfOrdinaryTax);
            projectWorkPay.setTotalValueAddedTax(totalValueAddedTax);
        }
        // 查询 HpProjectWorkPay 对象
        result.put("hpProjectWorkPay", projectWorkPay);
        if(projectWorkPay != null){
            Page<?> page = new Page<>();
            page.setCurrent(hpProjectWorkPay.getCurrent());
            page.setSize(hpProjectWorkPay.getSize());
            IPage<HpProjectWorkPayListNewVo> selectPage = hpProjectWorkPayListService.selectPageExpenses2(page, projectWorkPay.getProjectName());
            result.put("selectPage", selectPage);
            return ResultDto.ok(result);
        }else {
            return ResultDto.ok();
        }

    }





    /**
     * 点击项目名称查询详情分页
     */
    @PostMapping("/selectHpProjectWorkPayListByProjectName")
    public ResultDto selectHpProjectWorkPayListByProjectName(@RequestBody HpProjectWorkPay hpProjectWorkPay) {
        String projectName = hpProjectWorkPay.getProjectName();
        String incomeAndExpenditureTypes = hpProjectWorkPay.getIncomeAndExpenditureTypes();
        List<HpProjectWorkPayList> hpProjectWorkPayLists = hpProjectWorkPayListService.selectHpProjectWorkPayListByProjectName(projectName, incomeAndExpenditureTypes);
        return ResultDto.ok(hpProjectWorkPayLists);
    }


    /**
     * 根据projectWorkPayId查询 HpProjectWorkPayList 列表
     */
    @PostMapping("/listByProjectWorkPayId")
    public ResultDto listByProjectWorkPayId(Long projectWorkPayId) {
        List<HpProjectWorkPayList> hpProjectWorkPayLists = hpProjectWorkPayListService.getListByProjectWorkPayId(projectWorkPayId);
        return ResultDto.ok(hpProjectWorkPayLists);
    }

    /**
     * 批量删除明细数据
     */
    @GetMapping("/deleteById/{id}")
    public ResultDto deleteById(@PathVariable("id") Long id) {
        boolean b = hpProjectWorkPayListService.deleteById(id);
        if (b) {
            return ResultDto.ok();
        }
        return ResultDto.fail();
    }

    /**
     * 在回款明细列表对明细数据修改的保存
     */
    @PostMapping("/updateProjectWorkPayListData")
    public ResultDto updateProjectWorkPayListData(@RequestBody HpProjectWorkPayList hpProjectWorkPayList) {
        return hpProjectWorkPayListService.updateProjectWorkPayListData(hpProjectWorkPayList);
    }

    /**
     * 收入导出 填充方式
     * 需要的参数：Long projectWorkPayId
     */
    @GetMapping("/exportBaseOnClickProjectName/{projectName}")
    public void exportBaseOnClickProjectName(@PathVariable("projectName")  String projectName, HttpServletResponse response) throws IOException {
        log.info("收入导出 填充方式,参数：{}", projectName);
        if(projectName == null){
            // 重置response
            response.reset();
            response.setContentType("application/json");
            response.setCharacterEncoding("utf-8");
            JSONObject failureMsg = new JSONObject();
            failureMsg.put("status", "failure");
            failureMsg.put("message", "下载文件失败:项目回款主数据ID不可以为空！");
            response.getWriter().println(failureMsg.toString());
        }
        // 已收款总额
        BigDecimal   totalInPaid = new BigDecimal(0);
        // 未收款总额
        BigDecimal   totalInUnpaid = new BigDecimal(0);
        List<HpProjectWorkPayListVo> hpProjectWorkPayListVos = hpProjectWorkPayListService.selectListInCome(projectName);
        List<IncomeExportExcelVO> data = new ArrayList<>();
        for (int i = 0; i < hpProjectWorkPayListVos.size(); i++) {
            HpProjectWorkPayListVo hpProjectWorkPayListVo = hpProjectWorkPayListVos.get(i);
            IncomeExportExcelVO incomeExportExcelVO = new IncomeExportExcelVO();
            incomeExportExcelVO.setXh(i + 1);
            incomeExportExcelVO.setContractContent(hpProjectWorkPayListVo.getContractContent());
            incomeExportExcelVO.setAppointedTime(hpProjectWorkPayListVo.getAppointedTime());
            incomeExportExcelVO.setActualTime(hpProjectWorkPayListVo.getActualTime());
            incomeExportExcelVO.setContractAmount(hpProjectWorkPayListVo.getContractAmount());
            BigDecimal paid = hpProjectWorkPayListVo.getPaid();
            incomeExportExcelVO.setPaid(paid);
            totalInPaid = totalInPaid.add(paid);
            BigDecimal unpaid = hpProjectWorkPayListVo.getUnpaid();
            incomeExportExcelVO.setUnpaid(unpaid);
            totalInUnpaid = totalInUnpaid.add(unpaid);
            incomeExportExcelVO.setRemark(hpProjectWorkPayListVo.getRemark());
            data.add(incomeExportExcelVO);
        }
        QueryWrapper<HpProjectWorkPay> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("project_name",projectName);
        queryWrapper.eq("income_and_expenditure_types", IncomeAndExpenditureTypesEnum.INCOME.getValue());
        HpProjectWorkPay projectWorkPay = hpProjectWorkPayService.getOne(queryWrapper);
        IncomeExportExcelHeaderVO headerVO = new IncomeExportExcelHeaderVO();
        if(projectWorkPay != null){
            headerVO.setProjectName(projectWorkPay.getProjectName());
            headerVO.setTotalContractAmount(projectWorkPay.getTotalContractAmount());
        }
        headerVO.setTotalInPaid(totalInPaid);
        headerVO.setTotalInUnpaid(totalInUnpaid);


        // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
        String fileName = URLEncoder.encode(projectName+"收款报表-" + new SimpleDateFormat("yyyy-MM-dd").format(new Date()) + ".xlsx", "UTF-8");
        try {
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setCharacterEncoding("utf-8");
            response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName);
            // 生成sheet页签
            WriteSheet writeSheet = EasyExcel.writerSheet().build();
            InputStream inputStream = HpProjectWorkPayListController.class.getClassLoader().getResourceAsStream("exceltemplate/shouKuan.xlsx");
            ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream()).withTemplate(inputStream).excelType(ExcelTypeEnum.XLSX).build();
            // 添加头部
            excelWriter.fill(headerVO, writeSheet);
            // 添加明细数据
            excelWriter.fill(data, writeSheet);
            excelWriter.finish();
        } catch (Exception e) {
            // 重置response
            response.reset();
            response.setContentType("application/json");
            response.setCharacterEncoding("utf-8");
            JSONObject failureMsg = new JSONObject();
            failureMsg.put("status", "failure");
            failureMsg.put("message", "下载文件失败" + e.getMessage());
            response.getWriter().println(failureMsg.toString());
        }
    }


    /**
     * 支出导出 填充方式
     * 需要的参数：Long projectWorkPayId
     */
    @GetMapping("/exportBaseOnClickExpenses/{projectName}")
    public void exportBaseOnClickExpenses(@PathVariable("projectName")  String projectName, HttpServletResponse response) throws IOException {
        log.info("支出导出 填充方式,参数：{}", projectName);
        if(projectName == null){
            // 重置response
            response.reset();
            response.setContentType("application/json");
            response.setCharacterEncoding("utf-8");
            JSONObject failureMsg = new JSONObject();
            failureMsg.put("status", "failure");
            failureMsg.put("message", "下载文件失败:项目支付主数据项目名不可以为空！");
            response.getWriter().println(failureMsg.toString());
        }
        // 已收款总额
        BigDecimal   totalInPaid = new BigDecimal(0);
        // 未收款总额
        BigDecimal   totalInUnpaid = new BigDecimal(0);
        List<HpProjectWorkPayListVo> hpProjectWorkPayListVos = hpProjectWorkPayListService.selectListExpenses(projectName);
        List<ExpensesExportExcelVO> data = new ArrayList<>();
        for (int i = 0; i < hpProjectWorkPayListVos.size(); i++) {
            HpProjectWorkPayListVo hpProjectWorkPayListVo = hpProjectWorkPayListVos.get(i);
            ExpensesExportExcelVO expensesExportExcelVO = new ExpensesExportExcelVO();
            expensesExportExcelVO.setXh(i + 1);
            expensesExportExcelVO.setContractContent(hpProjectWorkPayListVo.getContractContent());
            expensesExportExcelVO.setAppointedTime(hpProjectWorkPayListVo.getAppointedTime());
            expensesExportExcelVO.setActualTime(hpProjectWorkPayListVo.getActualTime());
            expensesExportExcelVO.setContractAmount(hpProjectWorkPayListVo.getContractAmount());
            BigDecimal paid = hpProjectWorkPayListVo.getPaid();
            expensesExportExcelVO.setPaid(paid);
            totalInPaid = totalInPaid.add(paid);
            BigDecimal unpaid = hpProjectWorkPayListVo.getUnpaid();
            expensesExportExcelVO.setUnpaid(unpaid);
            totalInUnpaid = totalInUnpaid.add(unpaid);
            expensesExportExcelVO.setPayUnit(hpProjectWorkPayListVo.getPayUnit());
            expensesExportExcelVO.setRemark(hpProjectWorkPayListVo.getRemark());
            data.add(expensesExportExcelVO);
        }
        QueryWrapper<HpProjectWorkPay> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("project_name",projectName);
        queryWrapper.eq("income_and_expenditure_types", IncomeAndExpenditureTypesEnum.EXPENDITURE.getValue());
        HpProjectWorkPay projectWorkPay = hpProjectWorkPayService.getOne(queryWrapper);
        ExpensesExportExcelHeaderVO headerVO = new ExpensesExportExcelHeaderVO();
        if(projectWorkPay != null){
            headerVO.setProjectName(projectWorkPay.getProjectName());
            headerVO.setTotalContractAmount(projectWorkPay.getTotalContractAmount());
        }
        headerVO.setTotalInPaid(totalInPaid);
        headerVO.setTotalInUnpaid(totalInUnpaid);

        // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
        String fileName = URLEncoder.encode(projectName+"支付报表-" + new SimpleDateFormat("yyyy-MM-dd").format(new Date()) + ".xlsx", "UTF-8");
        try {
          //  response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setContentType("application/octet-stream");
            response.setCharacterEncoding("utf-8");
            response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName);
            // 生成sheet页签
            WriteSheet writeSheet = EasyExcel.writerSheet().build();
            InputStream inputStream = HpProjectWorkPayListController.class.getClassLoader().getResourceAsStream("exceltemplate/zhiFu.xlsx");
            ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream()).withTemplate(inputStream).excelType(ExcelTypeEnum.XLSX).build();
            // 添加头部
            excelWriter.fill(headerVO, writeSheet);
            // 添加明细数据
            excelWriter.fill(data, writeSheet);
            excelWriter.finish();
        } catch (Exception e) {
            // 重置response
            response.reset();
            response.setContentType("application/json");
            response.setCharacterEncoding("utf-8");
            JSONObject failureMsg = new JSONObject();
            failureMsg.put("status", "failure");
            failureMsg.put("message", "下载文件失败" + e.getMessage());
            response.getWriter().println(failureMsg.toString());
            /*if (!response.isCommitted()) {
                response.reset();
                response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            }else{
                // 重置response
                response.reset();
                response.setContentType("application/json");
                response.setCharacterEncoding("utf-8");
                JSONObject failureMsg = new JSONObject();
                failureMsg.put("status", "failure");
                failureMsg.put("message", "下载文件失败" + e.getMessage());
                response.getWriter().println(failureMsg.toString());
            }*/
        }
    }

    /**
     * 收款和支出明细数据单条新增
     * @param hpProjectWorkPayList
     * @return
     */
    @PostMapping("/oneHpProjectWorkPayListAdd")
    public ResultDto oneHpProjectWorkPayListAdd(@RequestBody HpProjectWorkPayList hpProjectWorkPayList){
        return hpProjectWorkPayListService.oneHpProjectWorkPayListAdd(hpProjectWorkPayList);
    }
    /**
     * 新增收款时，未收款金额接口
     */
    @PostMapping("/unpaidAmount")
    public ResultDto unpaidAmount(@RequestBody UnpaidAmountDto unpaidAmountDto){
        return hpProjectWorkPayListService.unpaidAmount(unpaidAmountDto);
    }
    /**
     * 修改收款时，未收款金额接口
     */
    @PostMapping("/unpaidAmountForUpdate")
    public ResultDto unpaidAmountForUpdate(@RequestBody UnpaidAmountDto unpaidAmountDto){
        return hpProjectWorkPayListService.unpaidAmountForUpdate(unpaidAmountDto);
    }



}